Daily trade alerts for ETH

Mark Ziemann https://mdz-analytics.com

2022-09-29

Source code

Intro

In the backtesting analysis, I have established several different profitable strategies for timing entry/exits. Visit the ETH page to see how these signals were identified.

  1. Simple moving average (SMA)

  2. Exponential moving average (EMA)

  3. SMA crosses

  4. EMA crosses

  5. Directional movement index (DMI)

  6. True strength index (TSI) BEST

  7. Stochastic oscillator (stoch)

  8. Double RSI

  9. Donchian channel

  10. Know sure thing (KST)

  11. Ensembl indicator

This script will examine the price action and these trade signals just before the daily close. If the signal is TRUE, it is bullish and if FALSE it is bearish. When there is a switch from bearish to bullish it is a buy signal and when it switches from bullish to bearish it is a sell signal. This HTML is updated just before the daily close each day, but push notifications for any trade signals are also sent by push bullet.

To receive these signals in real-time, subscribe to the following channels - it’s free for a limited time!

https://www.pushbullet.com/channel?tag=eth_signal

If you need some help to design your own trading signals/strategies, I am happy to help for a fee. email me at mark.ziemann{αt}gmail.com for any enquiries/suggestions/feedback.

This report is distributed for FREE under the MIT licence, but if you find it useful, consider a small tip.

Monero Address

Reminder: this analysis is not financial advice.

suppressPackageStartupMessages({
  library("jsonlite")
  library("tidyverse")
  library("runner")
  library("quantmod")
  library("TTR")
  library("RPushbullet")
  library("kableExtra")
})

TESTING = FALSE

MYNOTE = NULL
mydate <- Sys.time()
attr(mydate, "tzone") <- "UTC"
mydate <- as.Date(mydate)

Get ETH parameters

params <- read.table("https://mdz-analytics.com/coins/ETH/ETH_dat.txt", header=TRUE)
params %>% kbl(caption="optimised backtested parameters") %>%  kable_styling("hover", full_width = F)
optimised backtested parameters
indicator parameter meanROI totalROI ntrades ndays xhodl
SMA 34 1.722584 25090.450 69 2608 52.19604
EMA 17 1.151307 11986.489 135 2608 24.93567
SMAcross 21,12 1.492163 29253.179 55 2608 60.85583
EMAcross 16,13 2.532101 32319.366 32 2608 67.23447
DMI 16 1.842772 15390.796 63 2608 32.01771
DC 11 1.496811 25027.537 53 2608 52.06516
TSI 93,14,19 1.482050 10018.496 40 2608 20.84163
stoch 27,49,2 1.168702 11441.323 92 2608 23.80156
RSI2 103,107 1.415959 7572.955 62 2608 15.75413
KST 1.5,0.56,24 1.372597 14250.353 51 2608 29.64522
Ensemble SMAcross,EMA,DMI,stoch,RSI2,DC,KST,4 1.370224 56395.454 74 2608 149.73742

Get ETH price data

Obtaining ETH price data (daily) for the last 300 days and today’s price.

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=ETH&convert=USD&interval=daily&count=300"
download.file(URL,destfile="ethdat.txt")
ethdat <- fromJSON("ethdat.txt")
price <- ethdat$data$quotes
price <- data.frame(  as.Date(price$time_close) , price$quote$USD$high, price$quote$USD$low, price$quote$USD$close)
colnames(price) <- c("date","high","low","close")

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=ETH&convert=USD&interval=hourly&time_period=hourly&count=11"
download.file(URL,destfile="ethdat.txt")
ethdat <- fromJSON("ethdat.txt")
price2 <- ethdat$data$quotes
price2 <- data.frame( as.Date(price2$time_close) , price2$quote$USD$high, price2$quote$USD$low, price2$quote$USD$close,stringsAsFactors=FALSE)
colnames(price2) <- c("date","high","low","close")

high <- max(price2[,2])
low <-  min(price2[,3])
close <- price2[nrow(price2),4]

df <- data.frame(date=mydate,high=high,low=low,close=close,stringsAsFactors=FALSE)
price <- rbind(price,df)
tail(price) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close
2022-09-24 1346.255 1312.640 1317.993
2022-09-25 1333.371 1275.628 1294.217
2022-09-26 1335.526 1282.049 1335.320
2022-09-27 1396.892 1308.991 1330.128
2022-09-28 1351.965 1267.869 1337.411
2022-09-29 1343.665 1293.193 1329.132
if ( TESTING == TRUE) {
  price[nrow(price),"Close"] <- price[nrow(price),"Close"] * 2
}

ETH SMA indicator

Now to determine whether ETH has crossed the SMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "SMA",2])

price2$ma <- SMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-24 1346.255 1312.640 1317.993 1537.213 FALSE
2022-09-25 1333.371 1275.628 1294.217 1527.558 FALSE
2022-09-26 1335.526 1282.049 1335.320 1517.927 FALSE
2022-09-27 1396.892 1308.991 1330.128 1508.311 FALSE
2022-09-28 1351.965 1267.869 1337.411 1497.751 FALSE
2022-09-29 1343.665 1293.193 1329.132 1492.497 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMA=TRUE
} else {
  ens_SMA=FALSE
}

message(paste("ETH SMA signal:",eth_signal))
## ETH SMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="ETH w SMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( eth_signal != "NONE") {
  MYNOTE <- paste("The ETH SMA signal is", eth_signal,".")
}

ETH EMA indicator

Now to determine whether ETH has crossed the EMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "EMA",2])

price2$ma <- EMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-24 1346.255 1312.640 1317.993 1439.071 FALSE
2022-09-25 1333.371 1275.628 1294.217 1422.977 FALSE
2022-09-26 1335.526 1282.049 1335.320 1413.237 FALSE
2022-09-27 1396.892 1308.991 1330.128 1404.003 FALSE
2022-09-28 1351.965 1267.869 1337.411 1396.603 FALSE
2022-09-29 1343.665 1293.193 1329.132 1389.107 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMA=TRUE
} else {
  ens_EMA=FALSE
}

message(paste("ETH EMA signal:",eth_signal))
## ETH EMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="ETH EMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( eth_signal != "NONE") {
  MYNOTE <- paste("The ETH EMA signal is", eth_signal,".")
}

ETH SMA cross indicator

The SMA cross is a reasonably good strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "SMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- SMA(Cl(price2),n=n1)
price2$ma2 <- SMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-24 1346.255 1312.640 1317.993 1516.472 1404.435 FALSE
2022-09-25 1333.371 1275.628 1294.217 1502.975 1380.555 FALSE
2022-09-26 1335.526 1282.049 1335.320 1489.553 1355.602 FALSE
2022-09-27 1396.892 1308.991 1330.128 1478.524 1343.804 FALSE
2022-09-28 1351.965 1267.869 1337.411 1464.595 1335.885 FALSE
2022-09-29 1343.665 1293.193 1329.132 1450.014 1324.167 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMAcross=TRUE
} else {
  ens_SMAcross=FALSE
}

message(paste("ETH SMA cross signal:",eth_signal))
## ETH SMA cross signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="ETH w SMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The ETH SMA cross signal is", eth_signal,".")
}

ETH EMA cross indicator

The EMA cross is a moderately profitable strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "EMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- EMA(Cl(price2),n=n1)
price2$ma2 <- EMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-24 1346.255 1312.640 1317.993 1432.059 1408.395 FALSE
2022-09-25 1333.371 1275.628 1294.217 1415.843 1392.083 FALSE
2022-09-26 1335.526 1282.049 1335.320 1406.369 1383.974 FALSE
2022-09-27 1396.892 1308.991 1330.128 1397.400 1376.282 FALSE
2022-09-28 1351.965 1267.869 1337.411 1390.342 1370.729 FALSE
2022-09-29 1343.665 1293.193 1329.132 1383.141 1364.787 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMAcross=TRUE
} else {
  ens_EMAcross=FALSE
}

message(paste("ETH EMA cross signal is",eth_signal))
## ETH EMA cross signal is NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="ETH EMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The ETH EMA cross signal is", eth_signal,".")
}

ETH DMI indicator

Directional movement indicator is a good approach to identify trend changes.

n <- as.numeric(params[params$indicator == "DMI",2])

dmi.adx <- ADX(price[,c("high","low","close")],n=n)
price2 <- cbind(price,dmi.adx)
price2$signal <- dmi.adx[,1] > dmi.adx[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close DIp DIn DX ADX signal
2022-09-24 1346.255 1312.640 1317.993 12.38041 29.35322 40.66936 24.05796 FALSE
2022-09-25 1333.371 1275.628 1294.217 11.89462 30.71656 44.17135 25.31505 FALSE
2022-09-26 1335.526 1282.049 1335.320 11.60114 29.57035 43.64478 26.46066 FALSE
2022-09-27 1396.892 1308.991 1330.128 15.17572 27.75453 29.30057 26.63815 FALSE
2022-09-28 1351.965 1267.869 1337.411 14.28080 29.00146 34.01082 27.09894 FALSE
2022-09-29 1343.665 1293.193 1329.132 13.76129 27.94643 34.01082 27.53093 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_DMI=TRUE
} else {
  ens_DMI=FALSE
}

message(paste("ETH DMI signal:",eth_signal))
## ETH DMI signal: NONE
price2 <- as.data.frame(price2)
par(mfrow=c(2,1))
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="ETH USD price")
grid()
plot(price2$DIp~as.Date(price2$date),type="l", col="blue",
  xlab="Date",ylab="price (USD)",main="ETH DMI")
grid()
lines(price2$DIn ~ as.Date(price2$date) ,col="red")

if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH DMI signal is", eth_signal,".")
}

ETH TSI indicator

True Strength Indicator is one of the more profitable approaches. Its success lies in how it changes rapidly when momentum shifts. For most coins, this indicator performs “best” in backtesting analysis, which means it should carry relatively more weight than other indicators.

n <- as.numeric(unlist(strsplit(params[params$indicator == "TSI",2],",")))
n1 <- n[1]
n2 <- n[2]
ns <- n[3]

TSI <- function(x, n.first = 25, n.second = 13, n.signal = 7) {
  #True Strength Indicator
  #https://school.stockcharts.com/doku.php?id=technical_indicators:true_strength_index
  x <- try.xts(x, error = as.matrix)
  pc <- x - lag.xts(x, na.pad = T) #force lag.xts to get na padding
  dspc <- EMA(EMA(pc, n = n.first), n = n.second)
  dsapc <- EMA(EMA(abs(pc), n = n.first), n = n.second)

  tsi <- 100 * (dspc/dsapc)
  signal <- EMA(tsi, n = n.signal)
  r <- cbind(tsi, signal)
  r <- reclass(r, x)
  if (!is.null(dim(r))) colnames(r) <- c("tsi", "signal")
  return(r)
}

tsi <- TSI(price$close , n.first = n1, n.second = n2, n.signal = ns )
colnames(tsi) <- c("tsi","sig")

price2 <- cbind(price,tsi)
price2$signal <- tsi[,1] > tsi[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close tsi sig signal
2022-09-24 1346.255 1312.640 1317.993 -8.881822 -5.217921 FALSE
2022-09-25 1333.371 1275.628 1294.217 -9.318678 -5.627997 FALSE
2022-09-26 1335.526 1282.049 1335.320 -9.473622 -6.012559 FALSE
2022-09-27 1396.892 1308.991 1330.128 -9.629369 -6.374240 FALSE
2022-09-28 1351.965 1267.869 1337.411 -9.723936 -6.709210 FALSE
2022-09-29 1343.665 1293.193 1329.132 -9.842663 -7.022555 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_TSI=TRUE
} else {
  ens_TSI=FALSE
}

message(paste("ETH TSI signal:",eth_signal))
## ETH TSI signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(tsi[,1] ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="TSI",main="TSI")
lines(as.Date(price2$date), tsi[,2]  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH TSI signal is", eth_signal,".")
}

ETH stochastic oscillator indicator

Similar to the TSI, the stoch can pinpoint early changes in momentum, however it may give many false positives.

n <- as.numeric(unlist(strsplit(params[params$indicator == "stoch",2],",")))
n1 <- n[1]
n2 <- n[2]
n3 <- n[3]

sto <- stoch(HLC(price), nFastK=n1 , nFastD=n2 , nSlowD=n2 , bounded = TRUE, smooth=n3)

price2 <- cbind(price,sto)
price2$signal <- price2$fastK > price2$fastD

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close fastK fastD slowD signal
2022-09-24 1346.255 1312.640 1317.993 0.1688066 0.4137845 0.6340414 FALSE
2022-09-25 1333.371 1275.628 1294.217 0.1381414 0.3983319 0.6301123 FALSE
2022-09-26 1335.526 1282.049 1335.320 0.1537493 0.3824714 0.6255580 FALSE
2022-09-27 1396.892 1308.991 1330.128 0.1860974 0.3676802 0.6204086 FALSE
2022-09-28 1351.965 1267.869 1337.411 0.1879806 0.3528598 0.6146480 FALSE
2022-09-29 1343.665 1293.193 1329.132 0.1870839 0.3371956 0.6082457 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_stoch=TRUE
} else {
  ens_stoch=FALSE
}

message(paste("ETH stoch signal:",eth_signal))
## ETH stoch signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$fastK ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="stochastic oscillator")
lines(as.Date(price2$date), price2$fastD  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH Stoch signal is", eth_signal,".")
}

ETH double RSI indicator

Double RSI is simply two RSI lines.

n <- as.numeric(unlist(strsplit(params[params$indicator == "RSI2",2],",")))
n1 <- n[1]
n2 <- n[2]

rsi1 <- RSI(price$close,n=n1,maType=EMA)
rsi2 <- RSI(price$close,n=n2,maType=EMA)

price2 <- cbind(price,rsi1,rsi2)
price2$signal <- price2$rsi1 > price2$rsi2

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close rsi1 rsi2 signal
2022-09-24 1346.255 1312.640 1317.993 44.33661 44.34582 FALSE
2022-09-25 1333.371 1275.628 1294.217 43.98744 44.01175 FALSE
2022-09-26 1335.526 1282.049 1335.320 44.75435 44.74491 TRUE
2022-09-27 1396.892 1308.991 1330.128 44.67556 44.66962 TRUE
2022-09-28 1351.965 1267.869 1337.411 44.81450 44.80235 TRUE
2022-09-29 1343.665 1293.193 1329.132 44.68444 44.67823 TRUE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    eth_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    eth_signal="SELL"
  }
} else {
  eth_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_RSI2=TRUE
} else {
  ens_RSI2=FALSE
}

message(paste("ETH RSI signal:",eth_signal))
## ETH RSI signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1 ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="double RSI")
lines(as.Date(price2$date), price2$rsi2  , col="red"  )
grid()

par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1/price2$rsi2 ~ as.Date(price2$date),type="l",
  xlab="Date",ylab="RSI ratio",main="double RSI")
grid()
abline(h=1,lty=2,lwd=2)

par(mfrow=c(1,1))
if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH RSI2 signal is", eth_signal,".")
}

ETH Donchian channel indicator

n <- as.numeric(params[params$indicator == "DC",2])

price2 <- price[1:nrow(price)-1,]
dc <- DonchianChannel(price2$close,n=n)

price2$higher <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"high"] > dc[(i-1),"high"]
} ))
price2$lower <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"low"] < dc[(i-1),"low"]
} ))
price2 <- price2[price2$higher != price2$lower,]
# show changing rows only
price2 <- price2[c(NA,unlist(lapply(2:nrow(price2) , function(i) {
  price2$higher[i] != price2$higher[i-1]
}))),]
price2 <- price2[!is.na(price2$higher),]

previous_signal <- price2[nrow(price2),"higher"]

price2 <- price
dc <- DonchianChannel(price2$close,n=n)
colnames(dc) <- c("dchigh","dcmid","dclow")
price2 <- cbind(price2,dc)

tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close dchigh dcmid dclow
2022-09-24 1346.255 1312.640 1317.993 1634.755 1443.681 1252.608
2022-09-25 1333.371 1275.628 1294.217 1471.693 1362.151 1252.608
2022-09-26 1335.526 1282.049 1335.320 1469.742 1361.175 1252.608
2022-09-27 1396.892 1308.991 1330.128 1469.742 1361.175 1252.608
2022-09-28 1351.965 1267.869 1337.411 1377.541 1315.075 1252.608
2022-09-29 1343.665 1293.193 1329.132 1377.541 1315.075 1252.608
eth_signal="NONE"

# if we in negative territory, check whether time to buy
if ( previous_signal == FALSE ) {
  if ( price2[nrow(price2),"dchigh"] > price2[nrow(price2)-1,"dchigh"] ) {
    eth_signal="BUY"
  }
}

# if we in positive territory, check whether time to sell
if ( previous_signal == TRUE ) {
  if ( price2[nrow(price2),"dclow"] < price2[nrow(price2)-1,"dclow"] ) {
    eth_signal="SELL"
  }
}

if ( eth_signal=="NONE" ) {
  today_signal=previous_signal
} else {
  if (eth_signal=="BUY") { today_signal = TRUE }
  if (eth_signal=="SELL") { today_signal = FALSE }
}

if (today_signal==TRUE) {
  ens_DC=TRUE
} else {
  ens_DC=FALSE
}

message(paste("ETH DC signal:",eth_signal))
## ETH DC signal: NONE
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

price2 <- tail(price2,100)

plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dcmid~ as.Date(price2$date),lwd=1.5,col="gray")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH Donchian channel signal is", eth_signal,".")
}

ETH KST indicator

Another high-performing indicator across different price series data.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "KST",2],",")))
nScale <- n[1]
nrocScale <- n[2]
nSigs <- n[3]

kst <- KST(price2$close,n=nScale * c(10, 10, 10, 15) ,
  nROC=nrocScale * c(10, 15, 20, 30),
  nSig=nSigs)

price2 <- cbind(price2,kst)
price2$KST <- as.numeric(kst[,1]>kst[,2])

tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close kst signal KST
2022-09-24 1346.255 1312.640 1317.993 -78.68506 -48.57802 0
2022-09-25 1333.371 1275.628 1294.217 -92.48944 -49.17170 0
2022-09-26 1335.526 1282.049 1335.320 -103.65274 -49.83666 0
2022-09-27 1396.892 1308.991 1330.128 -114.01886 -50.85419 0
2022-09-28 1351.965 1267.869 1337.411 -119.00970 -52.19723 0
2022-09-29 1343.665 1293.193 1329.132 -122.66960 -53.93107 0
today_signal <- price2[nrow(price2),"KST"]
previous_signal <- price2[(nrow(price2)-1),"KST"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    signal="SELL"
  }
} else {
  signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_DMI=TRUE
} else {
  ens_DMI=FALSE
}

message(paste("ETH KST signal:",eth_signal))
## ETH KST signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(kst[,1] ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="KST",main="KST")
lines(as.Date(price2$date), kst[,2]  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH KST signal is", eth_signal,".")
}

ETH Ensemble indicator

This is a combination of a number of indicators.

ens <- params[params$indicator=="Ensemble","parameter"]
myrev <- intToUtf8(rev(utf8ToInt(ens)))
myrev <- unlist(strsplit(myrev,","))
# get thresh
n <- as.numeric(myrev[1])
myrev <- myrev[2:length(myrev)]
# get combination
combo <- sapply(myrev,function(s) { intToUtf8(rev(utf8ToInt(s))) })

message(paste("The combination is",paste(combo,collapse=" ")))
## The combination is KST DC RSI2 stoch DMI EMA SMAcross
message(paste("The buy threshold is",n))
## The buy threshold is 4
indicators <- c("SMA"=ens_SMA,
  "EMA"=ens_EMA,
  "SMAcross"=ens_SMAcross,
  "EMAcross"=ens_EMAcross,
  "DMI"=ens_DMI,
  "TSI"=ens_TSI,
  "stoch"=ens_stoch,
  "RSI2"=ens_RSI2,
  "DC"=ens_DC)

indicators <- indicators[names(indicators) %in% combo]
message("State of the indicators:")
## State of the indicators:
indicators
##      EMA SMAcross      DMI    stoch     RSI2       DC 
##    FALSE    FALSE    FALSE    FALSE     TRUE    FALSE
today_count <- sum(indicators)
message(paste("today_count_ETH",today_count,sep="="))
## today_count_ETH=1
today_signal <- today_count>=n

prev_html <- readLines("https://mdz-analytics.com/coins/ETH/alerts_ETH.html")
prev_signal <- length(grep("ETH ensemble indicator is BULLISH",prev_html))>2

eth_signal <- "NONE"

if ( today_signal != prev_signal ) {
  if ( today_signal == TRUE ) {
    eth_signal="BUY"
  } else {
    eth_signal="SELL"
  }
}

if (today_signal==TRUE) {
  message("ETH ensemble indicator is BULLISH")
} else {
  message("ETH ensemble indicator is BEARISH")
}
## ETH ensemble indicator is BEARISH
message(paste("ETH ENS signal:",eth_signal))
## ETH ENS signal: NONE
if ( eth_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"ETH Ensemble indicator is", eth_signal,".")
}

Send a push notification.

MYNOTE
## NULL
if ( !is.null(MYNOTE) ) {
  MYNOTE <- paste(MYNOTE, ". Visit https://mdz-analytics.com/coins/ETH/alerts_ETH.html for the details")
  MYNOTE
  pbPost("note", "Crypto Alert", MYNOTE ,channel="eth_signal")
}

Session information

For reproducibility


Click HERE to show session info

sessionInfo()
## R version 4.1.2 (2021-11-01)
## Platform: aarch64-unknown-linux-gnu (64-bit)
## Running under: Ubuntu 22.04.1 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/aarch64-linux-gnu/blas/libblas.so.3.10.0
## LAPACK: /usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3.10.0
## 
## locale:
##  [1] LC_CTYPE=en_AU.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_AU.UTF-8        LC_COLLATE=en_AU.UTF-8    
##  [5] LC_MONETARY=en_AU.UTF-8    LC_MESSAGES=en_AU.UTF-8   
##  [7] LC_PAPER=en_AU.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] kableExtra_1.3.4  RPushbullet_0.3.4 quantmod_0.4.20   TTR_0.24.3       
##  [5] xts_0.12.1        zoo_1.8-10        runner_0.4.1      forcats_0.5.1    
##  [9] stringr_1.4.0     dplyr_1.0.9       purrr_0.3.4       readr_2.1.2      
## [13] tidyr_1.2.0       tibble_3.1.8      ggplot2_3.3.6     tidyverse_1.3.2  
## [17] jsonlite_1.8.0   
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.4          sass_0.4.2          viridisLite_0.4.0  
##  [4] modelr_0.1.8        bslib_0.4.0         assertthat_0.2.1   
##  [7] highr_0.9           googlesheets4_1.0.1 cellranger_1.1.0   
## [10] yaml_2.3.5          pillar_1.8.0        backports_1.4.1    
## [13] lattice_0.20-45     glue_1.6.2          digest_0.6.29      
## [16] rvest_1.0.2         colorspace_2.0-3    htmltools_0.5.3    
## [19] pkgconfig_2.0.3     broom_1.0.0         haven_2.5.0        
## [22] bookdown_0.28       scales_1.2.0        webshot_0.5.3      
## [25] svglite_2.1.0       tzdb_0.3.0          googledrive_2.0.0  
## [28] generics_0.1.3      ellipsis_0.3.2      cachem_1.0.6       
## [31] withr_2.5.0         cli_3.3.0           magrittr_2.0.3     
## [34] crayon_1.5.1        readxl_1.4.1        evaluate_0.16      
## [37] fs_1.5.2            fansi_1.0.3         xml2_1.3.3         
## [40] tools_4.1.2         hms_1.1.1           gargle_1.2.0       
## [43] lifecycle_1.0.1     munsell_0.5.0       reprex_2.0.2       
## [46] compiler_4.1.2      jquerylib_0.1.4     systemfonts_1.0.4  
## [49] rlang_1.0.4         grid_4.1.2          rstudioapi_0.13    
## [52] rmarkdown_2.15      gtable_0.3.0        DBI_1.1.3          
## [55] curl_4.3.2          R6_2.5.1            lubridate_1.8.0    
## [58] knitr_1.39          fastmap_1.1.0       utf8_1.2.2         
## [61] stringi_1.7.8       parallel_4.1.2      rmdformats_1.0.4   
## [64] Rcpp_1.0.9          vctrs_0.4.1         dbplyr_2.2.1       
## [67] tidyselect_1.1.2    xfun_0.32